package com.itx.gatewayx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itx.gatewayx.domain.News;
import com.itx.gatewayx.domain.User;
import com.itx.gatewayx.domain.dto.NewsApiResponse;
import com.itx.gatewayx.mapper.NewsMapper;
import com.itx.gatewayx.service.NewsService;
import com.itx.gatewayx.service.UserService;
import com.itx.gatewayx.utils.HttpUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 新闻服务实现类
 *
 * @author itx
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NewsServiceImpl extends ServiceImpl<NewsMapper, News> implements NewsService {
    
    private final NewsMapper newsMapper;
    private final UserService userService;
    private final ObjectMapper objectMapper;
    
    @Value("${news.api.key:37b92cef4db482fe97ecd9b5d4b04f24}")
    private String apiKey;

    @Value("${news.api.url:http://v.juhe.cn/toutiao/index}")
    private String apiUrl;
    
    @Override
    public IPage<News> getNewsList(Long current, Long size, String categoryId) {
        Page<News> page = new Page<>(current, size);
        return newsMapper.selectNewsPage(page, categoryId);
    }
    
    @Override
    public News getNewsDetail(String newsId, Long userId) {
        // 获取新闻详情
        News news = this.getById(newsId);
        if (news == null || news.getDelFlag() == 1) {
            return null;
        }
        
        // 增加浏览量
        newsMapper.incrementViews(newsId);
        
        // 获取作者信息
        User author = userService.getById(news.getAuthorId());
        if (author != null) {
            news.setAuthor(author.getNickname());
            news.setAuthorAvatar(author.getAvatar());
        }
        
        // 获取分类名称（可以进一步优化为从缓存获取）
        // TODO: 从分类服务获取分类名称
        
        // 获取标签（实际实现需增加tags相关的mapper方法）
        // TODO: 获取文章标签
        news.setTags(new ArrayList<>());
        
        // 判断当前用户是否点赞、收藏
        if (userId != null) {
            // TODO: 实现判断用户是否点赞、收藏逻辑
            news.setIsLiked(false);
            news.setIsFavorite(false);
        }
        
        return news;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishNews(News news, List<String> tags) {
        // 设置状态和默认值
        news.setPublishTime(new Date());
        news.setUpdateTime(new Date());
        news.setViews(0);
        news.setLikes(0);
        news.setComments(0);
        news.setDelFlag(0);
        
        // 保存新闻
        boolean success = this.save(news);
        
        // 保存标签关联（实际实现需要增加tag相关的mapper）
        if (success && tags != null && !tags.isEmpty()) {
            // TODO: 实现保存标签逻辑
        }
        
        return success;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateNews(News news, List<String> tags) {
        // 检查新闻是否存在
        News existNews = this.getById(news.getUniquekey());
        if (existNews == null || existNews.getDelFlag() == 1) {
            return false;
        }
        
        // 设置更新时间
        news.setUpdateTime(new Date());
        
        // 不允许更新的字段
        news.setAuthorId(null);
        news.setPublishTime(null);
        news.setViews(null);
        news.setLikes(null);
        news.setComments(null);
        news.setDelFlag(null);
        
        // 更新新闻
        boolean success = this.updateById(news);
        
        // 更新标签关联（实际实现需要增加tag相关的mapper）
        if (success && tags != null) {
            // TODO: 实现更新标签逻辑
        }
        
        return success;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteNews(String newsId, Long userId) {
        // 检查新闻是否存在
        News news = this.getById(newsId);
        if (news == null || news.getDelFlag() == 1) {
            return false;
        }
        
        // 检查是否有权限删除
        if (!news.getAuthorId().equals(userId)) {
            // 检查是否为管理员
            User user = userService.getById(userId);
            if (user == null || !"admin".equals(user.getRole())) {
                return false;
            }
        }
        
        // 逻辑删除
        News updateNews = new News();
        updateNews.setUniquekey(news.getUniquekey());
        updateNews.setDelFlag(1);
        updateNews.setUpdateTime(new Date());
        
        return this.updateById(updateNews);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean likeNews(String newsId, Long userId, boolean isLike) {
        // 检查新闻是否存在
        News news = this.getById(newsId);
        if (news == null || news.getDelFlag() == 1) {
            return false;
        }
        
        // TODO: 实现点赞/取消点赞逻辑
        // 1. 查询是否已点赞
        // 2. 根据isLike决定点赞或取消点赞
        // 3. 更新新闻点赞数量
        
        // 简单实现: 直接更新点赞数
        int count = isLike ? 1 : -1;
        return newsMapper.updateLikes(newsId, count) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean favoriteNews(String newsId, Long userId, boolean isFavorite) {
        // 检查新闻是否存在
        News news = this.getById(newsId);
        if (news == null || news.getDelFlag() == 1) {
            return false;
        }
        
        // TODO: 实现收藏/取消收藏逻辑
        // 1. 查询是否已收藏
        // 2. 根据isFavorite决定收藏或取消收藏
        
        return true;
    }
    
    @Override
    public List<News> getHotNews(int limit) {
        return newsMapper.selectHotNews(limit);
    }
    
    @Override
    public IPage<News> searchNews(Long current, Long size, String keyword) {
        Page<News> page = new Page<>(current, size);
        return newsMapper.searchNews(page, keyword);
    }
    
    @Override
    public IPage<News> getUserNews(Long current, Long size, Long userId) {
        Page<News> page = new Page<>(current, size);
        
        LambdaQueryWrapper<News> queryWrapper = new LambdaQueryWrapper<News>()
                .eq(News::getAuthorId, userId)
                .eq(News::getDelFlag, 0)
                .orderByDesc(News::getPublishTime);
        
        return this.page(page, queryWrapper);
    }
    
    @Override
    public IPage<News> getUserFavorites(Long current, Long size, Long userId) {
        Page<News> page = new Page<>(current, size);
        
        // TODO: 实现查询用户收藏的新闻
        // 这需要news_favorite表的支持
        
        return page;
    }

    @Override
    public NewsApiResponse fetchNewsFromApi(Map<String, String> params) {
        try {
            if (params == null) {
                params = Collections.emptyMap();
            }
            
            // 添加API密钥
            Map<String, String> requestParams = new HashMap<>(params);
            requestParams.put("key", apiKey);

            // 发送请求
            String response = HttpUtils.doGet(apiUrl, requestParams);
            return objectMapper.readValue(response, NewsApiResponse.class);
        } catch (Exception e) {
            log.error("获取新闻API数据失败", e);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveNewsList(List<News> newsList) {
        if (newsList == null || newsList.isEmpty()) {
            return;
        }
        
        // 确保每条新闻都有唯一的uniquekey
        for (News news : newsList) {
            if (news.getUniquekey() == null || news.getUniquekey().trim().isEmpty()) {
                // 如果uniquekey为空，生成一个新的
                news.setUniquekey("news_" + UUID.randomUUID().toString().replace("-", ""));
            }
        }

        // 过滤掉已经存在的新闻
        List<News> uniqueNewsList = new ArrayList<>();
        for (News news : newsList) {
            // 根据uniquekey查询新闻是否已存在
            News existingNews = this.getById(news.getUniquekey());
            if (existingNews == null) {
                // 如果不存在，则添加到待保存列表
                uniqueNewsList.add(news);
            } else {
                log.debug("新闻已存在，跳过保存: {}", news.getTitle());
            }
        }
        
        if (uniqueNewsList.isEmpty()) {
            log.info("所有新闻已存在，无需保存");
            return;
        }
        
        // 批量保存新闻
        this.saveBatch(uniqueNewsList);
        log.info("成功保存{}条新闻数据", uniqueNewsList.size());
    }

    @Override
    public List<News> convertFromApiResponse(NewsApiResponse response) {
        if (response == null || response.getResult() == null || response.getResult().getData() == null) {
            return Collections.emptyList();
        }
        
        List<News> newsList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        for (NewsApiResponse.NewsData data : response.getResult().getData()) {
            try {
                News news = new News();
                
                // 设置API返回的字段
                news.setUniquekey(data.getUniquekey());
                news.setTitle(data.getTitle());
                news.setCategory(data.getCategory());
                news.setAuthorName(data.getAuthorName());
                news.setUrl(data.getUrl());
                news.setThumbnailPicS(data.getThumbnailPicS());
                news.setThumbnailPicS02(data.getThumbnailPicS02());
                news.setThumbnailPicS03(data.getThumbnailPicS03());
                news.setIsContent(data.getIsContent());
                
                // 设置日期
                try {
                    Date newsDate = dateFormat.parse(data.getDate());
                    news.setDate(newsDate);
                    news.setPublishTime(newsDate);
                } catch (Exception e) {
                    log.warn("新闻日期解析失败: {}, 使用当前时间", data.getDate());
                    Date now = new Date();
                    news.setDate(now);
                    news.setPublishTime(now);
                }
                
                // 设置创建时间和更新时间
                Date now = new Date();
                news.setCreateTime(now);
                news.setUpdateTime(now);
                
                // 设置默认值
                news.setViews(0);
                news.setLikes(0);
                news.setComments(0);
                news.setDelFlag(0);
                news.setStatus(1); // 已发布状态
                
                // 从标题生成摘要
                if (data.getTitle() != null) {
                    String title = data.getTitle();
                    String summary = title.length() > 100 ? title.substring(0, 100) : title;
                    news.setSummary(summary);
                    // 设置content字段，避免数据库插入错误
                    news.setContent(summary);
                } else {
                    // 确保content字段不为空
                    news.setSummary("");
                    news.setContent("");
                }
                
                // 设置封面图片
                if (StringUtils.hasText(data.getThumbnailPicS())) {
                    news.setCoverImg(data.getThumbnailPicS());
                }
                
                // 设置分类ID (使用分类名称作为ID)
                if (StringUtils.hasText(data.getCategory())) {
                    news.setCategoryId(data.getCategory());
                    news.setCategoryName(data.getCategory());
                }
                
                // 设置作者相关信息
                if (StringUtils.hasText(data.getAuthorName())) {
                    // 在实际项目中，可以根据作者名查找用户ID
                    // 这里简单设置默认值
                    news.setAuthor(data.getAuthorName());
                    news.setAuthorId(1L); // 默认作者ID
                } else {
                    // 确保author_id字段不为空
                    news.setAuthorId(1L); // 默认作者ID
                }
                
                newsList.add(news);
            } catch (Exception e) {
                log.error("转换新闻数据失败: {}", data.getUniquekey(), e);
            }
        }
        
        return newsList;
    }

    @Override
    public List<News> getLatestNews() {
        LambdaQueryWrapper<News> queryWrapper = new LambdaQueryWrapper<News>()
                .eq(News::getDelFlag, 0)
                .eq(News::getStatus, 1)
                .orderByDesc(News::getPublishTime)
                .last("LIMIT 20");
                
        return this.list(queryWrapper);
    }

    @Override
    public List<News> getNewsByCategory(String category) {
        if (!StringUtils.hasText(category)) {
            return Collections.emptyList();
        }
        
        LambdaQueryWrapper<News> queryWrapper = new LambdaQueryWrapper<News>()
                .eq(News::getCategory, category)
                .eq(News::getDelFlag, 0)
                .eq(News::getStatus, 1)
                .orderByDesc(News::getPublishTime);
                
        return this.list(queryWrapper);
    }

    @Override
    public Page<News> queryNewsPage(Page<News> page, News news) {
        LambdaQueryWrapper<News> queryWrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        queryWrapper.eq(News::getDelFlag, 0);
        
        if (news != null) {
            if (StringUtils.hasText(news.getTitle())) {
                queryWrapper.like(News::getTitle, news.getTitle());
            }
            
            if (StringUtils.hasText(news.getCategory())) {
                queryWrapper.eq(News::getCategory, news.getCategory());
            }
            
            if (news.getStatus() != null) {
                queryWrapper.eq(News::getStatus, news.getStatus());
            }
            
            if (news.getAuthorId() != null) {
                queryWrapper.eq(News::getAuthorId, news.getAuthorId());
            }
        }
        
        // 默认按发布时间降序排序
        queryWrapper.orderByDesc(News::getPublishTime);
        
        return this.page(page, queryWrapper);
    }
} 